package eval.engine;

import java.util.List;
import java.util.Map;
import eval.engine.cplex.CplexMapIndexToVmId;
import eval.engine.cplex.InitialCplexCode.CplexDataHolder;
import eval.host.Host;
import eval.vm.VMIdentifier;
import eval.vm.VirtualMachine;

/**
 * Interface for a placement object. Each placement technique (e.g. CPLEX,
 * FIRE FIGHTING, OPEN STACK) implement their own placement class.
 * 
 * @author Amit Peled   <amit.kapina@gmail.com>
 * @author Igal Kaufman <igal.kaufman@gmail.com>  
 * */


public interface IPlacement {

	//####### CLOUD #######

	/**
	 * return the amount of CPU requested to be deployed in the cloud.
	 * includes the demand of rejected VMs
	 * 
	 * @return total requested CPU
	 */
	public abstract int getTotalRequestedCPU();

	/**
	 * return the value of current CPU load in the Cloud.
	 * 
	 * @return total cloud CPU Load
	 */
	public abstract int getTotalCloudCPULoad();

	/**
	 * return the value of current CPU demand in the cloud.
	 * 
	 * @return total CPU demand of cloud
	 */
	public abstract double getTotalCloudCpuDemand();
	/**
	 * return the value of current MEMORY demand in the cloud.
	 *  
	 * @return total MEM demand of cloud
	 */
	public abstract int getTotalCloudMemDemand();

	//####### HOSTS #######

	/**
	 *  return a list of hosts that turned on in current placement.
	 *  
	 * @return list of hosts
	 */
	public abstract List<Host> getTurnedONHosts();

	/**
	 * return a list of hosts that turned off in current placement.
	 * 
	 * @return list of hosts
	 */
	public abstract List<Host> getTurnedOFFHosts();

	/**
	 * the loud of the host with the minimum CPU load.
	 * 
	 * @return the MIN CPU 
	 */
	public abstract double getMinCPULoadInHosts();

	/**
	 * the loud of the host with the minimum MEM load.
	 * 
	 * @return MIN MEM 
	 */
	public abstract double getMinMEMLoadInHosts();

	/**
	 * return the average CPU load of all hosts => totalCPULoad / numberOfAllHost
	 * 
	 * @return average CPU
	 */
	public abstract double getAvgCPULoadInHosts();

	/**
	 * return the average memory load of all hosts.
	 * 
	 * @return average MEM
	 */
	public abstract double getAvgMEMLoadInHosts();

	/**
	 * return the load of the host with the maximum cpu load.
	 *  
	 * @return MAX CPU
	 */
	public abstract double getMaxCPULoadInHosts();

	/**
	 * the load of the host with the maximum MEM load.
	 * 
	 * @return MAX MEM
	 */
	public abstract double getMaxMEMLoadInHosts();

	/**
	 * return the number of open hosts.
	 * 
	 * @return number of open hosts
	 */
	public abstract int getNumberOfOpenHosts();

	/**
	 * return the number of closed hosts.
	 * 
	 * @return number of close hosts
	 */
	public abstract int getNumberOfClosedHosts();

	/**
	 * return the number of hosts that candidates for closing.
	 * 
	 * @return number of candidates for closing hosts
	 */
	public abstract int getNumberOfCandidatesForClosingHosts();

	/**
	 * return the number of VMs that have been turned off during current placement.
	 * 
	 * @return number of turn off hosts
	 */
	public abstract int getNumberOfTurnOffHosts();

	/**
	 * return the number of VMs that have been turned on during current placement.
	 * 
	 * @return number of turn on hosts
	 */
	public abstract int getNumberOfTurnOnHosts();


	//####### VIRTUAL MACHINES #######

	//	In the meantime,I comment this function,as this information can be collected from vmMaping.
	//	//return a list of VMS deployed in the cloud.
	//	public abstract List<VirtualMachine> getVMSinCloud();

	/**
	 * return a list of VMS that request to be deployed in the cloud. includes rejected vms.
	 * 
	 * @return number of new VMs to be deploy
	 */
	public List<VirtualMachine> getVMSrequestedTobedeployed();

	/**
	 * return a list of VMS in the cloud with Satisfied Demand.
	 * 
	 * @return list of VMs 
	 */
	public List<VirtualMachine> getVMSWithSatisfiedDemand();

	/**
	 * return a list of VMS in the cloud with unsatisfied Demand.
	 *  not include rejected vm's.
	 * 
	 * @return list of VMs
	 */
	public List<VirtualMachine> getVMSWithUNSatisfiedDemand();

	/**
	 * return a list of VMS that rejected from being deployed in the cloud.
	 * 
	 * @return list of VMs
	 */
	public List<VirtualMachine> getRejectedVMS();

	/**
	 * return a list of VMS that been removed in current placement.
	 * 
	 * @return list of VMs
	 */
	public List<VirtualMachine> getRemovedList();

	/**
	 * return a list of VMS that have been placed in current placement.
	 * 
	 * @return list of VMs
	 */
	public List<VirtualMachine> getPlacedList();

	/**
	 * return the number of VMs currently deploy in the cloud.
	 * 
	 * @return nuber of VMs at cloud
	 */
	public abstract int getNumberOfVMsAtCloud();

	/**
	 * return the number of VMs with satisfied demand.
	 * 
	 * @return number of VMs with satisfied demand
	 */
	public abstract int getNumberOfVMsWithSatisfiedDemand();

	/**
	 * return the number of VMs with unsatisfied demand.
	 * 
	 * @return number of VMs with unsatisfied demand
	 */
	public abstract int getNumberOfVMsWithUnSatisfiedDemand();

	/**
	 * return the sum of the demand of all satisfied VMs.
	 * 
	 * @return total satisfied CPU demand
	 */
	public abstract int getTotalSatisfiedCPUDemand();

	/**
	 * return the sum of the demand of all unsatisfied VMs.
	 * 
	 * @return total unsatisfied CPU demand
	 */
	public abstract int getTotalUnSatisfiedCPUDemand();

	/**
	 * return the number of VMs that have been removed during this placement.
	 * 
	 * @return total number of remove VMs
	 */
	public abstract int getNumberOfRemovedVMs();

	/**
	 * return the number of VMs deployed in current tick.
	 * 
	 * @return total number of deployed VMs
	 */
	public abstract int getNumberOfPlacedVMs();


	//####### PLACEMENT #######

	/**
	 * return whether current placement is empty or not
	 * 
	 * @return true if this is empty placement, false otherwise
	 */
	public abstract boolean isEmptyPlacement();

	/**
	 * return the current cloud map placement
	 * key: host
	 * value: list of VMs
	 * 
	 * @return current placement map
	 */
	public  Map<Host, List<VirtualMachine>> getvmMapping();

	/**
	 * return if host are open or not.
	 * 
	 * @param host the host to check
	 * @return true if host is open, false otherwise
	 */
	public abstract boolean isHostOpen(Host host);

	/**
	 * return if host are close or not.
	 * 
	 * @param host the host to check
	 * @return true if host is close, false otherwise
	 */
	public abstract boolean isHostClose(Host host);

	/**
	 * return specific host from last placement.
	 *  
	 * @param host the host to check
	 * @return the host
	 */
	public abstract Host getHostFromLastPlacement(Host host);

	/**
	 * return  map of the cloud 
	 * key: id of host
	 * value: id of VM
	 * 
	 * @return current placement map
	 */
	public Map<Integer, List<VMIdentifier>> getCloudMap();

	/**
	 * return list of all open hosts.
	 * 
	 * @return open hosts
	 */
	public List<Integer> getOpenHosts();

	/**
	 * return the number of  VMs to be deploy.
	 * 
	 * @return number of VMs to be deploy
	 */
	public abstract int getNumberOfVmsReqToBeDeploy();

	/**
	 * return the total CPU capacity of open hosts at current placement
	 * 
	 * @return total CPU capacity at open hosts 
	 */
	public abstract int getTotalCpuCapcityAtOpenHosts();

	/**
	 * return the total CPU capacity of hosts (include the closed one). 
	 *  
	 * @return total CPU capacity of cloud
	 */
	public abstract int getTotalCpuCapcityAtCloud();

	/**
	 * return the total MEM capacity of open hosts at current placement
	 * 
	 * @return total MEM capacity at open hosts
	 */
	public abstract int getTotalMemCapcityAtOpenHosts();

	/**
	 * return the total MEM capacity of hosts (include the closed one).
	 * 
	 * @return total MEM capacity of cloud
	 */
	public abstract int getTotalCloudMemAtCloud();

	/**
	 * return the cost of the energy of host that opened at the current placement
	 * 
	 * @return the energy cost at $
	 */
	public abstract double getHostsStartUpCost();

	/**
	 * return the cost of the energy of satisfied demand  
	 * 
	 * @return the energy cost at $
	 */
	public abstract double getWorkingHostCost();

	/**
	 * return the income on satisfied CPU demand
	 * 
	 * @return the total income at $
	 */
	public abstract double getIncomeForSatisfyDemand();

	/**
	 * return the total MEM load on cloud
	 * 
	 * @return total cloud MEM load
	 */
	public abstract int getTotalMemLoadAtCloud();

	/**
	 * return the cost of the energy of open host 
	 * (the basic electricity consumption of hosts)
	 * 
	 * @return the total cost at $
	 */
	public abstract double getBaseHostCost();

	/**
	 * return the number of VMs that relocate from host i to host j 
	 * at current placement
	 * 
	 * @return number of relocation
	 */
	public abstract int getVmRelocate();

	/**
	 * return the sum of CPU reservation  of all VMS at cloud
	 * 
	 * @return total CPU reservation 
	 */
	public abstract double getSumOfMinReservtion();

	/**
	 * for CPLEX engine only.
	 * return the map translator from CPLEX index to VM id
	 * 
	 * @return the index translator
	 */
	public abstract CplexMapIndexToVmId getCplexMapIndexToVmId();

	/**
	 * for CPLEX engine only.
	 * return the referent placement from the CPLEX engine
	 * 
	 * @return CPLEX placement
	 */
	public abstract CplexDataHolder getCplexData();

	/**
	 * return the total MEM capacity at cloud
	 * 
	 * @return total MEM capacity
	 */
	public abstract int getTotalMemCapcityAtCloud();

	/**
	 * return the CPU that not used at hosts
	 * when at place i at the return array sit the data of host id i
	 * 
	 * @return array of free CPU 
	 */
	public abstract double[] getFreeCpuAtHosts();

	/**
	 * return the cloud gradient of CPU at current placement 
	 * 
	 * @return the gradient
	 */
	public abstract int getGradientValue();



}